package com.geecity.flowable.flowabledemo.util;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author yuanDing
 * @version 1.0
 * @date 2025-07-24 10:30
 */

@Slf4j
public class DispatchUtil {
    private static final int SSH_TIMEOUT = 3;



    /**
     * 检查SSH连接是否可用
     * 执行流程：
     * 1. 构建SSH测试命令
     * 2. 执行命令并读取输出
     * 3. 检查是否有权限错误
     * 4. 返回检查结果
     *
     * 错误处理：
     * - 命令执行超时返回false
     * - 权限拒绝返回false
     * - 其他异常返回false
     *
     * @param serverIp 目标服务器IP
     * @return 连接是否可用
     */
    public static boolean checkSshConnection(String serverIp) {
        String checkCommand = String.format("ssh -o BatchMode=yes -o ConnectTimeout=%d %s echo test",
                SSH_TIMEOUT, serverIp);
        
        log.info("开始检查SSH连接，目标服务器: {}", serverIp);
        log.info("执行SSH连接检查命令: {}", checkCommand);
        
        try {
            Process process = Runtime.getRuntime().exec(checkCommand);
            boolean finished = process.waitFor(SSH_TIMEOUT, TimeUnit.SECONDS);
            int exitValue = process.exitValue();
            
            log.info("SSH连接检查结果 - 服务器: {}, 命令完成: {}, 退出码: {}", serverIp, finished, exitValue);
            
            boolean result = finished && exitValue == 0;
            if (result) {
                log.info("SSH连接检查成功，服务器: {} 连接正常", serverIp);
            } else {
                log.warn("SSH连接检查失败，服务器: {}, 原因: {}", serverIp, 
                    !finished ? "命令执行超时" : "退出码异常(" + exitValue + ")");
            }
            
            return result;
        } catch (Exception e) {
            log.error("SSH连接检查异常，服务器: {}, 命令: {}", serverIp, checkCommand, e);
            return false;
        }
    }

    /**
     * 执行远程命令
     * 执行流程：
     * 1. 构建SSH命令
     * 2. 执行命令并读取输出
     * 3. 返回命令执行结果
     *
     * 错误处理：
     * - 命令执行异常返回空字符串
     * - 超时返回空字符串
     *
     * @param serverIp 目标服务器IP
     * @param command 要执行的命令
     * @return 命令执行结果
     */
    public static String executeRemoteCommand(String serverIp, String command) {
        log.info("开始执行远程命令，服务器: {}", serverIp);
        log.info("原始命令: {}", command);
        
        // 使用数组方式构建命令，避免shell解析问题
        String[] cmdArray = {
            "ssh",
            "-o", "BatchMode=yes",
            "-o", "ConnectTimeout=" + SSH_TIMEOUT,
            serverIp,
            command
        };
        
        log.info("SSH命令数组: {}", String.join(" ", cmdArray));
        
        try {
            long startTime = System.currentTimeMillis();
            Process process = Runtime.getRuntime().exec(cmdArray);
            
            if (process.waitFor(30, TimeUnit.SECONDS)) {
                long endTime = System.currentTimeMillis();
                int exitValue = process.exitValue();
                
                log.info("远程命令执行完成，服务器: {}, 退出码: {}, 耗时: {}ms", 
                    serverIp, exitValue, (endTime - startTime));
                
                if (exitValue == 0) {
                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"))) {
                        String result = reader.lines().collect(Collectors.joining("\n"));
                        log.info("远程命令执行成功，服务器: {}, 输出长度: {} 字符", serverIp, result.length());
                        log.debug("远程命令输出内容: {}", result);
                        return result;
                    }
                } else {
                    // 读取错误输出
                    try (BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"))) {
                        String errorOutput = errorReader.lines().collect(Collectors.joining("\n"));
                        log.error("远程命令执行失败，服务器: {}, 退出码: {}, 错误输出: {}", 
                            serverIp, exitValue, errorOutput);
                    } catch (Exception e) {
                        log.error("读取错误输出失败", e);
                    }
                    return "";
                }
            } else {
                log.error("远程命令执行超时(30秒)，服务器: {}, 命令: {}", serverIp, command);
                process.destroyForcibly();
                return "";
            }
        } catch (Exception e) {
            log.error("执行远程命令异常，服务器: {}, 命令: {}", serverIp, command, e);
            return "";
        }
    }
}
